﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.SharePoint;
namespace SPEasyCode
{
    /// <summary>
    /// Type Represents all keyword manipulations 
    /// </summary>
    public class LineProcesser
    {
        /// <summary>
        /// Key world list
        /// </summary>
        /// <returns></returns>
        public static List<string> KeyWords()
        {
            List<string> keyWords = new List<string>();
            keyWords.Add("Foreach");
            return keyWords;
        }

        /// <summary>
        /// Check for the <%lists%> key word 
        /// </summary>
        /// <param name="line">current text line</param>
        /// <returns>True if the key exists; otherwise, False </returns>
        public static bool ForeachList(string line)
        {
            Regex regexText = new Regex(Constants.ListKeyIdentifier);
            return ForLoop(line) && regexText.IsMatch(line);
        }


        /// <summary>
        /// Check for the loop end key word 
        /// </summary>
        /// <param name="line">current text line</param>
        /// <returns>True if the key exists; otherwise, False </returns>
        public static bool LoopEnd(string line)
        {
            Regex regexText = new Regex(Constants.LoopEndIdentifier);
            return regexText.IsMatch(line);
        }

        /// <summary>
        /// Check for the loop start key word 
        /// </summary>
        /// <param name="line">current text line</param>
        /// <returns>True if the key exists; otherwise, False </returns>
        public static bool LoopStart(string line)
        {
            Regex regexText = new Regex(Constants.LoopStartIdentifier);
            return regexText.IsMatch(line);
        }

        /// <summary>
        /// Check for the for each field key word 
        /// </summary>
        /// <param name="line">current text line</param>
        /// <returns>True if the key exists; otherwise, False </returns>
        public static bool ForeachField(string line)
        {
            Regex regexText = new Regex(Constants.FieldIdentifier);
            return regexText.IsMatch(line);
        }

        /// <summary>
        /// Check for the instruction key word 
        /// </summary>
        /// <param name="line">current text line</param>
        /// <returns>True if the key exists; otherwise, False </returns>
        public static bool InstructionLine(string line)
        {
            Regex regexText = new Regex(Constants.InstructionIdentifier);
            return regexText.IsMatch(line) && line.Length > 2 && line.Trim().Substring(0, 2) == Constants.InstructionIdentifier;
        }

        /// <summary>
        /// Check for the if condition
        /// </summary>
        /// <param name="line">current text line</param>
        /// <returns>True if the key exists; otherwise, False </returns>
        public static bool IfCodition(string line)
        {
            Regex regexText = new Regex(Constants.IfCoditionIdentifier);
            return regexText.IsMatch(line);
        }
        /// <summary>
        /// Check for the else condition
        /// </summary>
        /// <param name="line">current text line</param>
        /// <returns>True if the key exists; otherwise, False </returns>
        public static bool ElseCodition(string line)
        {
            Regex regexText = new Regex(Constants.ElseCoditionIdentifier);
            return regexText.IsMatch(line);
        }
        /// <summary>
        /// Check for the if condition is True or not
        /// </summary>
        /// <param name="line">current text line</param>
        /// <returns>True if the condition is true; otherwise, False </returns>
        public static bool IfCoditionTrue(string line)
        {
            line = line.Replace(Constants.IfCoditionIdentifier, string.Empty).Replace(")", string.Empty).Replace("(", string.Empty);
            if (line.IndexOf("==") > -1)
            {
                line = line.Trim();
                string a = line.Split(new string[] { "==" }, StringSplitOptions.RemoveEmptyEntries)[0];
                string b = line.Split(new string[] { "==" }, StringSplitOptions.RemoveEmptyEntries)[1];
                if (a == b)
                { return true; }
                else
                    return false;
            }
            else if (line.IndexOf("!=") > -1)
            {

                line = line.Trim();
                string a = line.Split(new string[] { "!=" }, StringSplitOptions.RemoveEmptyEntries)[0];
                string b = line.Split(new string[] { "!=" }, StringSplitOptions.RemoveEmptyEntries)[1];
                if (a != b)
                { return true; }
                else
                    return false;
            }
            return false;

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="segment"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static string GetFieldChoiseValues(string segment, string name)
        {
            if (name != null)
            {
                Regex regexText = new Regex(Constants.FieldChoiceValues);
                return regexText.Replace(segment, name);
            }
            return segment;
        }

        public static string GetNumberFormat(string segment, string name)
        {
            if (name != null)
            {
                Regex regexText = new Regex(Constants.NumberFieldFormatIdentifier);
                return regexText.Replace(segment, name);
            }
            return segment;
        }

        public static string GetFieldLookupListTitle(string segment, string name)
        {
            if (name!=null)
            {
                Regex regexText = new Regex(Constants.FieldLookupListTitle);
                return regexText.Replace(segment, name);
            }
            return segment;
        }
        public static void SetVariable(string value)
        {
            string tempVariable = string.Empty;
            string tempVaribaleName = string.Empty;
            if (value.IndexOf("var") > -1 && value.IndexOf("=") > -1)
            {
                tempVariable = value.Split('=')[1].Trim();
                tempVaribaleName = value.Trim().Split('=')[0].Replace("var",string.Empty ).Replace ("=",string.Empty ).Replace(">>",string.Empty ).Trim();
                if (GlobalData.SPACVariables.ContainsKey(tempVaribaleName))
                {
                    GlobalData.SPACVariables[tempVaribaleName] = tempVariable;
                }
                else
                {
                    GlobalData.SPACVariables.Add(tempVaribaleName, tempVariable);
                }
            }
            else if (value.IndexOf("Set") > -1 && value.IndexOf("=") > -1)
            {
                tempVariable = value.Split('=')[1].Trim ();
                tempVaribaleName = value.Trim().Split('=')[0].Replace("Set", string.Empty).Replace("=", string.Empty).Replace(">>", string.Empty).Trim();
                if (GlobalData.SPACVariables.ContainsKey(tempVaribaleName))
                {
                    GlobalData.SPACVariables[tempVaribaleName] = tempVariable;
                }
                
            }
            
            
        }

        public static bool MatchVariableName(string line , string varibaleName)
        {
            Regex regexText = new Regex(varibaleName.Trim ());
            return regexText.IsMatch(line.Trim ());
        }

        public static string ReplaceVariableName(string line)
        {
            foreach (KeyValuePair<string, string> currentVariable in GlobalData.SPACVariables)
            {
                if (currentVariable.Key != null && currentVariable.Value != null)
                {
                    if (MatchVariableName(line, currentVariable.Key))
                    {
                        Regex regexText = new Regex(currentVariable.Key);
                        line = regexText.Replace(line, currentVariable.Value);
                    }
                }
            }
            return line;
        }


        /// <summary>
        /// Check for the for loop key word 
        /// </summary>
        /// <param name="line">current text line</param>
        /// <returns>True if the key exists; otherwise, False </returns>
        public static bool ForLoop(string line)
        {
            Regex regexText = new Regex(Constants.ForEachIdentifier);
            return regexText.IsMatch(line);
        }

        /// <summary>
        /// Check for the data type key word 
        /// </summary>
        /// <param name="line">current text line</param>
        /// <returns>True if the key exists; otherwise, False </returns>
        public static bool DataType(string line)
        {
            Regex regexText = new Regex(Constants.DataTypeIdentifier);
            return regexText.IsMatch(line);
        }

        /// <summary>
        /// Replace variable name key word with corresponding value 
        /// </summary>
        /// <param name="segment">Current text</param>
        /// <param name="name">Corresponding value to replace</param>
        /// <returns>Key world replaced text</returns>
        public static string GetVariableName(string segment, string name)
        {
            Regex regexText = new Regex(Constants.FieldNameIdentifier);
            return regexText.Replace(segment, name.Replace(" ", string.Empty));
        }

        /// <summary>
        ///  Replace Internal Field Name Identifier key word with corresponding value 
        /// </summary>
        /// <param name="segment">Current text</param>
        /// <param name="name">Corresponding value to replace</param>
        /// <returns>Key world replaced text</returns>
        public static string GetInternalFieldName(string segment, string name)
        {
            Regex regexText = new Regex(Constants.InternalFieldNameIdentifier);
            return regexText.Replace(segment, name.Replace(" ", string.Empty));
        }
        /// <summary>
        /// Replace Display Name Identifier key word with corresponding value 
        /// </summary>
        /// <param name="segment">Current text</param>
        /// <param name="name">Corresponding value to replace</param>
        /// <returns>Key world replaced text</returns>
        public static string GetDispalyName(string segment, string name)
        {
            Regex regexText = new Regex(Constants.DisplayNameIdentifier);
            return regexText.Replace(segment, name);
        }

        /// <summary>
        /// Replace SP Data Type Identifier key word with corresponding value 
        /// </summary>
        /// <param name="segment">Current text</param>
        /// <param name="name">Corresponding value to replace</param>
        /// <returns>Key world replaced text</returns>
        public static string GetSPDataType(string segment, string name)
        {
            Regex regexText = new Regex(Constants.SPDataTypeIdentifier);
            return regexText.Replace(segment, name.Replace(" ", string.Empty));
        }
        /// <summary>
        /// Replace Required Field Identifier key word with corresponding value 
        /// </summary>
        /// <param name="segment">Current text</param>
        /// <param name="name">Corresponding value to replace</param>
        /// <returns>Key world replaced text</returns>
        public static string GetRequiredField(string segment, string name)
        {
            Regex regexText = new Regex(Constants.RequiredFieldIdentifier);
            return regexText.Replace(segment, name.Replace(" ", string.Empty));
        }

        /// <summary>
        /// Check for the for save key word 
        /// </summary>
        /// <param name="line">current text line</param>
        /// <returns>True if the key exists; otherwise, False </returns>
        public static bool Save(string line)
        {
            Regex regexText = new Regex(Constants.SaveIdentifier);
            return regexText.IsMatch(line);
        }

        /// <summary>
        /// Check for the for save end key word 
        /// </summary>
        /// <param name="line">current text line</param>
        /// <returns>True if the key exists; otherwise, False </returns>
        public static bool SaveEnd(string line)
        {
            Regex regexText = new Regex(Constants.SaveEndIdentifier);
            return regexText.IsMatch(line);
        }
        /// <summary>
        /// Check for the for save start key word 
        /// </summary>
        /// <param name="line">current text line</param>
        /// <returns>True if the key exists; otherwise, False </returns>
        public static bool SaveStart(string line)
        {
            Regex regexText = new Regex(Constants.SaveStartIdentifier);
            return regexText.IsMatch(line);
        }

        /// <summary>
        /// Replace List Name Identifier key word with corresponding value 
        /// </summary>
        /// <param name="segment">Current text</param>
        /// <param name="name">Corresponding value to replace</param>
        /// <returns>Key world replaced text</returns>
        public static string GetListName(string segment, string name)
        {
            Regex regexText = new Regex(Constants.ListNameIdentifier);
            return regexText.Replace(segment, name.Replace(" ", string.Empty));
        }

        /// <summary>
        /// Replace List Title Identifier key word with corresponding value 
        /// </summary>
        /// <param name="segment">Current text</param>
        /// <param name="name">Corresponding value to replace</param>
        /// <returns>Key world replaced text</returns>
        public static string GetListTitle(string segment, string name)
        {
            Regex regexText = new Regex(Constants.ListTitleIdentifier);
            return regexText.Replace(segment, name);
        }

        /// <summary>
        /// Replace Lookup List Guid Identifier key word with corresponding value 
        /// </summary>
        /// <param name="segment">Current text</param>
        /// <param name="name">Corresponding value to replace</param>
        /// <returns>Key world replaced text</returns>
        public static string GetLookupListGuid(string segment, string name)
        {
            if (!string.IsNullOrEmpty(name))
            {
                Regex regexText = new Regex(Constants.FieldLookupListGuid);
                return regexText.Replace(segment, name);
            }
            return segment;
        }

        /// <summary>
        /// Replace lower case list name identifier key word with corresponding value 
        /// </summary>
        /// <param name="segment">Current text</param>
        /// <param name="name">Corresponding value to replace</param>
        /// <returns>Key world replaced text</returns>
        public static string GetToLowerListName(string segment, string name)
        {
            Regex regexText = new Regex(Constants.ListNameToLowerIdentifier);
            name = name.Replace(" ", string.Empty);
            if (segment.Length > 1)
                return regexText.Replace(segment, name.Substring(0, 1).ToLower() + name.Replace(" ", string.Empty).Substring(1, name.Length - 1));
            else
                return segment.ToLower();
        }

        /// <summary>
        /// Replace lower case field name Identifier key word with corresponding value 
        /// </summary>
        /// <param name="segment">Current text</param>
        /// <param name="name">Corresponding value to replace</param>
        /// <returns>Key world replaced text</returns>
        public static string GetToLowerFieldName(string segment, string name)
        {
            Regex regexText = new Regex(Constants.FieldNameToLowerIdentifier);
            name = name.Replace(" ", string.Empty);
            if (segment.Length > 1)
                return regexText.Replace(segment, name.Substring(0, 1).ToLower() + name.Substring(1, name.Length - 1));
            else
                return segment.ToLower();
        }
        /// <summary>
        /// Replace insturction lines with emtpy values
        /// </summary>
        /// <param name="segment">Current text</param>
        /// <param name="name">Corresponding value to replace</param>
        /// <returns>Key world replaced text</returns>
        public static string RemoveInstruction(string segment)
        {
            Regex regexText = new Regex(Constants.InstructionIdentifier);
            return regexText.Replace(segment, string.Empty);
        }
        /// <summary>
        /// Replace List Guid Identifier key word with corresponding value 
        /// </summary>
        /// <param name="segment">Current text</param>
        /// <param name="name">Corresponding value to replace</param>
        /// <returns>Key world replaced text</returns>
        public static string GetListGuid(string segment,string name)
        {
            Regex regexText = new Regex(Constants.ListGuidFieldIdentifier);
            return regexText.Replace(segment, name);
        }

        /// <summary>
        /// Get class name
        /// </summary>
        /// <param name="segment">Current text</param>
        /// <returns>valid class name</returns>
        public static string GetClassFileName(string segment)
        {
            return segment.Replace(Constants.SaveIdentifier, string.Empty).Replace(Constants.SaveEndIdentifier, string.Empty).Replace("(", string.Empty).Replace(")", string.Empty);
        }
        /// <summary>
        /// Remove SPAC key words from the text
        /// </summary>
        /// <param name="segment">Current text</param>
        /// <returns>Key word removed text</returns>
        public static string RemoveKeyWords(string segment)
        {
            string tempsegment = segment;
            foreach (string key in KeyWords())
            {
                Regex regexText = new Regex(key);
                tempsegment = regexText.Replace(tempsegment, string.Empty);
            }
            return tempsegment;
        }
 
        /// <summary>
        /// Get C# data type for SharePoint data type
        /// </summary>
        /// <param name="segment">Current text</param>
        /// <param name="field">Current SharePoint field</param>
        /// <returns>C# data type</returns>
        public static string GetDataType(string segment, SPField field)
        {

            Regex regexText = new Regex(Constants.DataTypeIdentifier);
            string dataType = string.Empty;
            switch (field.Type.ToString().ToLower())
            {
                case "text":
                    dataType = CDataTypes.CString;
                    break;
                case "note":
                    dataType = CDataTypes.CString;
                    break;
                case "boolean":
                    dataType = CDataTypes.CBoolean;
                    break;
                case "user":
                    dataType = CDataTypes.CString;
                    break;
                case "choice":
                    dataType = CDataTypes.CString;
                    break;
                case "lookup":
                    dataType = CDataTypes.CString;
                    break;
                case "number":
                    SPFieldNumber numberField = field as SPFieldNumber;
                    if (numberField.DisplayFormat == SPNumberFormatTypes.NoDecimal)
                        dataType = CDataTypes.Cint;
                    else
                        dataType = CDataTypes.CDubble;
                    break;
                case "currency":
                    dataType = CDataTypes.CDubble;
                    break;
                case "datetime":
                    dataType = CDataTypes.CDatetime;
                    break;
                case "url":
                    dataType = CDataTypes.CUrl;
                    break;
                default:
                    dataType = CDataTypes.CString;
                    break;
            }

            return regexText.Replace(segment, dataType);
        }

        /// <summary>
        /// Get valid convert opertion for SharePoint field
        /// </summary>
        /// <param name="segment">Current Line</param>
        /// <param name="field">SharePoint field</param>
        /// <returns>Convert to data type</returns>
        public static string GetConvertType(string segment, SPField field)
        {

            Regex regexText = new Regex(Constants.DataTypeConvertionIdentifier);
            string dataType = string.Empty;
            switch (field.Type.ToString().ToLower())
            {

                case "text":
                    dataType = CDataTypesConvertion.ToString;
                    break;
                case "note":
                    dataType = CDataTypesConvertion.ToString;
                    break;
                case "boolean":
                    dataType = CDataTypesConvertion.ToBoolean;
                    break;
                case "user":
                    dataType = CDataTypesConvertion.ToString;
                    break;
                case "choice":
                    dataType = CDataTypesConvertion.ToString;
                    break;
                case "lookup":
                    dataType = CDataTypesConvertion.ToString;
                    break;
                case "number":
                     SPFieldNumber numberField = field as SPFieldNumber;
                    if (numberField.DisplayFormat == SPNumberFormatTypes.NoDecimal)
                        dataType = CDataTypesConvertion.ToInt32;
                    else
                        dataType = CDataTypesConvertion.ToDouble;
                    break;
                case "currency":
                    dataType = CDataTypesConvertion.ToDouble;
                    break;
                case "datetime":
                    dataType = CDataTypesConvertion.ToDateTime;
                    break;
                default:
                    dataType = CDataTypesConvertion.ToString;
                    break;
            }

            return regexText.Replace(segment, dataType);
        }
    }
}
